/*    file: main.cpp
 *    desc:
 * 
 * created: 2016-04-06
 *  author: chuanjiang.zh@qq.com
 * company: 
 */

#include <stdio.h>
#include <iostream>

#include "BasicType.h"
#include "PsCaster.h"
#include "Ffmpeg.h"
#include "SharedPtr.h"
#include "TFileUtil.h"
#include <assert.h>
#include "H264PropParser.h"
#include "TByteBuffer.h"
#include "LoopReader.h"
#include "AutoMFormat.h"
#include "ScopedAVPacket.h"


extern "C"
{
#include "libavutil/time.h"
}


static bool hasPrefix(const uint8_t* data, int size)
{
    assert(size >= 4);
    if ((data[0] == 0) && (data[1] == 0))
    {
        if ((data[2] == 0) && (data[3] == 1))
        {
            return true;
        }
        if (data[2] == 1)
        {
            return true;
        }
    }
    return false;
}

class Application
{
public:
    Application()
    {
        av_register_all();
        avformat_network_init();

        pscaster_init();
    }

    ~Application()
    {
        pscaster_quit();
    }

};

void DemoCasterEventCallback(const CasterEvent* event, void* context)
{
    printf("caster event. handle: %d, event: %d\n", event->handle, event->type);
}


int main(int argc, char** argv)
{
	std::string filename = "rtsp://admin:sjld16301@192.168.3.65/";
	if (argc > 1)
    {
		filename = argv[1];
    }

    Application app;

    LoopReader reader;
    int rc = reader.open(filename.c_str());
    if (rc != 0)
    {
        return false;
    }

    AutoMFormat fmt;

    fmt.width = reader.m_width;
    fmt.height = reader.m_height;
    fmt.framerate = reader.m_fps;
    fmt.codec = reader.m_codec;
    fmt.setProp((uint8_t*)(reader.m_prop.c_str()), reader.m_prop.size());

    fmt.channels = reader.m_channels;
    fmt.sampleRate = reader.m_sampleRate;
    fmt.audioCodec = reader.m_acodec;
    fmt.setConfig((uint8_t*)(reader.m_config.c_str()), reader.m_config.size());

    
    pscaster_t videoHandle = -1;
    pscaster_t audioHandle = -1;

	PsCasterParams params;
	params.payload = 96;
	params.ssrc = 0x02;
    params.es = 1;

    rc = pscaster_openEx(&videoHandle, PSCASTER_PROTOCOL_RTP, 0, &fmt, &params);

    params.payload = 0;
    rc = pscaster_openEx(&audioHandle, PSCASTER_PROTOCOL_RTP, 0, &fmt, &params);

    {
        pscaster_close(videoHandle);
        videoHandle = -1;

        pscaster_close(audioHandle);
        audioHandle = -1;

        params.payload = 96;
        rc = pscaster_openEx(&videoHandle, PSCASTER_PROTOCOL_RTP, 0, &fmt, &params);

        params.payload = 0;
        rc = pscaster_openEx(&audioHandle, PSCASTER_PROTOCOL_RTP, 0, &fmt, &params);
    }


    pscaster_setEventCallback(videoHandle, DemoCasterEventCallback, NULL);

    rc = pscaster_add_target(videoHandle, "192.168.3.123", 10000);
    assert(rc == 0);

    rc = pscaster_add_target(audioHandle, "192.168.3.123", 10002);
    assert(rc == 0);

    int64_t tmStart = av_gettime_relative();
    int64_t videoDuration = 0;
    int64_t audioDuration = 0;

	int count = 1000;
    while (true)
    {
		//count--;
		if (count <= 0)
		{
			break;
		}

        AVPacket pkt;
        av_init_packet(&pkt);

        int rc = reader.read(pkt);
        if (rc != 0)
        {
            break;
        }

        ScopedAVPacket scopedPkt(&pkt);

        MPacket mpkt = MPacket();
        mpkt.data = pkt.data;
        mpkt.size = pkt.size;
        mpkt.pts = pkt.dts;
        mpkt.flags = pkt.flags;
        mpkt.duration = pkt.duration;

        int delay = 0;
        if (pkt.stream_index == MTYPE_VIDEO)
        {
            pscaster_write(videoHandle, &mpkt);
        }
        else if (pkt.stream_index == MTYPE_AUDIO)
        {
            pscaster_write(audioHandle, &mpkt);
        }

    }

    std::cin.get();

    pscaster_close(videoHandle);
    pscaster_close(audioHandle);

    reader.close();

	return 0;
}




